<!--
 - MineAdmin is committed to providing solutions for quickly building web applications
 - Please view the LICENSE file that was distributed with this source code,
 - For the full copyright and license information.
 - Thank you very much for using MineAdmin.
 -
 - @Author X.Mo<root@imoi.cn>
 - @Link   https://gitee.com/xmo/mineadmin-vue
-->
<template>
  <div class="w-full p-2 resource-container h-full lg:flex lg:justify-between rounded-sm">
    <a-modal v-model:visible="openNetworkModal" :ok-text="$t('sys.save')" :on-before-ok="saveNetworkImg" draggable>
      <template #title>{{ $t('maResource.saveNetworkImage') }}</template>
      <a-input v-model="networkImg" class="mb-3" :placeholder="$t('maResource.networkImageNotice')" allow-clear />
      <a-image :src="networkImg" width="100%" style="min-height: 150px;" />
    </a-modal>
    <div class="lg:w-1/5 w-full p-2 shadow">
      <ma-tree-slider
        :data="sliderData"
        :search-placeholder="$t('maResource.searchResource')"
        :field-names="{ title: 'title', key: 'key' }"
        @click="handlerClick"
        icon="icon-folder"
        v-model="defaultKey"
      />
    </div>
    <div class="w-full lg:ml-3 mt-3 lg:mt-2 flex flex-col">
      
      <div class="lg:flex lg:justify-between">
        <div class="flex">
          <ma-upload v-model="uploadFile" multiple :show-list="false" type="chunk" :resource="false" />
          <a-button class="ml-3" @click="openNetworkModal = true">
            <icon-image /> {{ $t('maResource.saveNetworkImage') }}
          </a-button>
        </div>
        <a-input
          v-model="filename"
          class="input-search lg:mt-0 mt-2"
          :placeholder="$t('maResource.searchFileNotice')"
          @press-enter="searchFile"
        />
      </div>
      <a-spin :loading="resourceLoading" :tip="$t('maResource.loadingText')" class="h-full">
        <div class="resource-list mt-2" ref="rl" v-if="attachmentList && attachmentList.length > 0">
          <div
            class="item rounded-sm"
            v-for="(item, index) in attachmentList"
            :key="item.hash"
            @click="selectFile(item, index)"
          >
            <img
              :src="
                ! /^(http|https)/g.test(item.url)
                ? $tool.attachUrl(item.url, getStoreMode(item.storage_mode))
                : item.url
              "
              v-if="item.mime_type.indexOf('image') !== -1"
            />
            <div v-else class="text-3xl w-full h-full flex items-center justify-center">
              {{`.${item.suffix}`}}
            </div>
            <a-tooltip position="bottom">
              <div class="file-name">
                {{ item.origin_name }}
              </div>
              <template #content>
                <div>存储名称：{{ item.object_name }}</div>
                <div>存储目录：{{ item.storage_path }}</div>
                <div>上传时间：{{ item.created_at }}</div>
                <div>文件大小：{{ item.size_info }}</div>
                <div>存储模式：{{ getStoreMode(item.storage_mode) }}</div>
              </template>
            </a-tooltip>
          </div>
        </div>
        <a-empty v-else class="mt-10" />
      </a-spin>
      <div class="lg:flex lg:justify-between">
        <a-pagination
          :total="pageInfo.total"
          v-model:current="pageInfo.currentPage"
          v-model:page-size="pageSize"
          @change="changePage"
        />
        <a-button type="primary" @click="selectComplete" class="mt-3 lg:mt-0">{{ $t('maResource.ok') }}</a-button>
      </div>
    </div>
  </div>
</template>

<script setup>
  import { ref, onMounted, watch } from 'vue'
  import MaUpload from '@cps/ma-upload/index.vue'
  import uploadConfig from '@/config/upload'
  import MaTreeSlider from '@cps/ma-treeSlider/index.vue'
  import commonApi from '@/api/common'
  import { xor } from 'lodash'
  import tool from '@/utils/tool'
  import { useI18n } from 'vue-i18n'
  import { Message } from '@arco-design/web-vue'

  const { t } = useI18n()
  const sliderData = ref([])
  const defaultKey = ref(['all'])
  const uploadFile = ref()
  const attachmentList = ref([])
  const openNetworkModal = ref(false)
  const networkImg = ref()
  const pageInfo = ref({
    total: 1,
    currentPage: 1
  })
  const resourceLoading = ref(true)
  const pageSize = ref(30)
  const filename = ref()
  const selecteds = ref()
  const rl = ref()

  const emit = defineEmits([ 'update:modelValue' ])

  const props = defineProps({
    modelValue: { type: [ String, Array ] },
    multiple: { type: Boolean, default: true },
    onlyData: { type: Boolean, default: true },
    returnType: { type: String, default: 'hash'},
  })
  
  onMounted(async () => {
    const treeData = await commonApi.getDict('attachment_type')
    treeData.data.unshift({ title: '所有', key: 'all' })
    sliderData.value = treeData.data
    await getAttachmentList({pageSize: 1})

    if (props.multiple) {
      selecteds.value = []
    }
  })

  const getStoreMode = (mode) => {
    return uploadConfig.storageMode[mode.toString()]
  }

  const getAttachmentList = async (params = {}) => {
    const requestParams = Object.assign(params, { pageSize: pageSize.value })
    resourceLoading.value = true
    const response = await commonApi.getResourceList(requestParams)
    pageInfo.value = response?.data?.pageInfo
    attachmentList.value = response?.data?.items
    resourceLoading.value = false
  }

  const handlerItemClick = (e) => {
    console.log(e)
  }

  const handlerClick = async (item) => {
    defaultKey.value = item
    const type = item[0] === 'all' ? undefined : item[0]
    await getAttachmentList({ mime_type: type })
  }

  const searchFile = async () => {
    await getAttachmentList({ origin_name: filename.value })
  }

  const selectFile = (item, index) => {

    const children = rl.value.children
    const className = 'item rounded-sm'

    if (! /^(http|https)/g.test(item.url)) {
      item.url = tool.attachUrl(item.url, getStoreMode(item.storage_mode))
    }
    if (children[index].className.indexOf('active') !== -1) {
      children[index].className = className
      if (props.multiple) {
        selecteds.value.map((file, idx) => {
          selecteds.value.splice(idx, 1)
        })
      } else {
        selecteds.value = ''
      }
    } else {
      if (props.multiple) {
        children[index].className = className + ' active'
        selecteds.value.push(props.onlyData ? item[props.returnType] : item)
      } else {
        if (document.querySelectorAll('.item.active').length < 1) {
          children[index].className = className + ' active'
          selecteds.value = props.onlyData ? item[props.returnType] : item
        }
      }
    }
  }

  const clearSelecteds = () => {
    if (rl.value && rl.value.children) {
      const children = rl.value.children
      for (let i = 0; i < children.length; i++) {
        children[i].className = 'item rounded-sm'
      }
    }
    if (props.multiple) {
      selecteds.value = []
    } else {
      selecteds.value = undefined
    }
  }

  const selectComplete = () => {
    const files = props.multiple ? Object.assign([], selecteds.value) : selecteds.value
    emit('update:modelValue', files)
  }

  const changePage = async (page) => {
    await getAttachmentList({ page })
  }

  const saveNetworkImg = async(done) => {
    if (! networkImg.value) {
      Message.error(t('maResource.networkImageNotice'))
      done(false)
      return
    }
    const response = await commonApi.saveNetWorkImage({ url: networkImg.value })
    if (response.success) {
      Message.success(response.message)
      await getAttachmentList()
      networkImg.value = undefined
      done(true)
    } else {
      Message.error(response.message)
      done(false)
    }
  }

  watch(
    () => uploadFile,
    async () => await getAttachmentList(),
    { deep: true }
  )

  defineExpose({ clearSelecteds })
</script>

<style scoped lang="less">
.input-search {
  width: 252px;
}
.resource-list {
  display: flex;
  width: 100%;
  flex-wrap: wrap;
  flex-direction: row;
  align-content: center;
  .item {
    width: 130px; height: 130px; border: 2px solid var(--color-fill-1);
    margin-right: 10px; margin-bottom: 20px;
    background-color: var(--color-fill-1); 
    cursor: pointer; position: relative;
    .file-name {
      position: absolute; bottom: 0px; height: 23px;
      width: 100%; background: rgba(100, 100, 100, 0.3); line-height: 23px;
      font-size: 12px; overflow: hidden; padding: 0 10px;
      text-align: center; text-overflow: ellipsis;
      color: #fff;
    }
    img {
      width: 100%; height: 100%; object-fit: contain;
    }
  }
  .item:hover {
    border: 2px solid rgb(var(--primary-6));
  }
  .item.active {
    border: 2px solid rgb(var(--primary-6));
  }
  .item.active::after {
    content: ''; position: absolute;
    width: 126px; height: 126px; z-index: 2;
    top: 0;
    background: rgba(var(--primary-5), 0.2);
  }

}
</style>
